package com.panel;

import com.entity.*;
import com.util.GameUtil;
import com.view.GameFrame;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Arrays;

/**
 * @author: Combo
 * @time: 2020/12/31 18:02
 * @description:
 */
public class GamePanel extends JPanel implements KeyListener {
    public Image background;   // 背景图
    public Image score;        // 分数背景图
    public Image pause;        // 暂停图
    public Image proceed;      // 继续图

    // 玩家宠物
    public Person person;      // 人物
    public Pet pet;            // 宠物
    public Harpoon harpoon;    // 鱼叉
    public Gold gold;          // 金币

    // 障碍物
    public Crab[] crabs = {};          // 螃蟹
    public Missile[] missiles = {};    // 导弹
    public Harpoon[] harpoons = {};    // 鱼叉
    public Gold[] golds = {};          // 金币
    public Integer x = 0;              // 背景图片初始位置
    public Integer index = 0;          // 障碍物初始

    public boolean flag = true;
    public static boolean isGameOver = false;

    public GamePanel() {
        person = new Person();
        pet = new Pet();
        background = GameUtil.getImage("images/background.png");
        score = GameUtil.getImage("images/score.png");
        pause = GameUtil.getImage("images/pause.png");
        proceed = GameUtil.getImage("images/proceed.png");
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        if (flag){
            x -= 20; // 图片滚动速度
        }

        g.drawImage(background, x, 0, GameFrame.WIDTH, GameFrame.HEIGHT, null);
        g.drawImage(background, x + GameFrame.WIDTH, 0, GameFrame.WIDTH, GameFrame.HEIGHT, null);

        // 实现图片滚动切换
        if (x <= -GameFrame.WIDTH){
            x = 0;
        }
        person.paintPerson(g);      // 绘制人物
        pet.paintPet(g);            // 绘制宠物
        for (int i = 0; i < crabs.length; i++){
            crabs[i].paintCrab(g);  // 绘制螃蟹
        }
        for (int i = 0; i < harpoons.length; i++){
            harpoons[i].paintHarpoon(g); // 绘制鱼钩
        }
        for (int i = 0; i < golds.length; i++){
            golds[i].paintGold(g);  // 绘制金币
        }

        // 绘制分数
        g.drawImage(score, 120, 50, null);
        g.setColor(Color.ORANGE);
        g.setFont(new Font("楷体", Font.BOLD, 30));
        g.drawString("玩家得分: "+ person.getScore() + "分", 133, 95);

        if (flag){
            g.drawImage(proceed, 200, 800, 90, 90, null);
        } else {
            g.drawImage(pause, 200, 800, 90, 90, null);
        }
    }

    /**
     * 一直生成障碍物
     */
    public void produceObstacle(){
        index++;

        if (index % 100 == 0){
            // 生成一个螃蟹
            Crab crab1 = new Crab();
            crabs = Arrays.copyOf(crabs, crabs.length + 1);
            crabs[crabs.length - 1] = crab1;

            Missile missile1 = new Missile();
            missiles = Arrays.copyOf(missiles, missiles.length + 1);
            missiles[missiles.length - 1] = missile1;

            Harpoon harpoon1 = new Harpoon();
            harpoons = Arrays.copyOf(harpoons, harpoons.length + 1);
            harpoons[harpoons.length - 1] = harpoon1;
        }

        if (index % 15 == 0){
            Gold gold1 = new Gold();
            golds = Arrays.copyOf(golds, golds.length + 1);
            golds[golds.length - 1] = gold1;
        }
    }

    /**
     * 移动
     */
    public void step(){
        person.step();
        person.drop();
        pet.drop();

        // 螃蟹的移动
        for (int i=0; i<crabs.length; i++){
            crabs[i].step();
            // 判断当前障碍物是否越界
            if (crabs[i].outOfBounds()){
                // 去掉越界的障碍物
                crabs[i] = crabs[crabs.length - 1]; // 将数组最后一个元素赋值给越界的障碍物，间接删除
                crabs = Arrays.copyOf(crabs, crabs.length - 1);
            }
        }

        pet.step();

        for (int i = 0; i < missiles.length; i++){
            missiles[i].step();
            if (missiles[i].outOfBounds()){
                missiles[i] = missiles[missiles.length - 1];
                missiles = Arrays.copyOf(missiles, missiles.length -1);
            }
        }

        for (int i=0; i<harpoons.length; i++){
            harpoons[i].step();
            if (harpoons[i].outOfBounds()){
                harpoons[i] = harpoons[harpoons.length - 1];
                harpoons = Arrays.copyOf(harpoons, harpoons.length -1);
            }
        }

        for (int i=0; i<golds.length; i++){
            golds[i].step();
            if (golds[i].outOfBounds()){
                golds[i] = golds[golds.length - 1];
                golds = Arrays.copyOf(golds, golds.length -1);
            }
        }
    }

    /**
     * 碰撞
     */
    public void collide(){
        // 人物与螃蟹是否碰撞
        for (int i = 0; i < crabs.length; i++){
            if (person.getX() + Person.WIDTH >= crabs[i].getX() &&
                person.getX() <= crabs[i].getX() + Crab.WIDTH &&
                person.getY() + Person.HEIGHT >= crabs[i].getY() &&
                person.getY() <= crabs[i].getY() + Crab.HEIGHT){
                if (person.getX() + Person.WIDTH <= crabs[i].getX() + Crab.WIDTH){
                    // 左碰撞 -- 防止人在右边，碰撞后可以闯过障碍物
                    person.setX(crabs[i].getX() - Crab.WIDTH);
                } else {
                    // 右碰撞
                    person.setX(crabs[i].getX() + Crab.WIDTH);
                }
            }
        }

        // 人物与导弹是否碰撞
        for (int i = 0; i < missiles.length; i++){
            if (person.getX() + Person.WIDTH >= missiles[i].getX() &&
                person.getX() <= missiles[i].getX() + Missile.WIDTH &&
                person.getY() + Person.HEIGHT >= missiles[i].getY() &&
                person.getY() <= missiles[i].getY() + Missile.HEIGHT){
                if (person.getX() + Person.WIDTH <= missiles[i].getX() + Missile.WIDTH){
                    // 左碰撞 -- 玩家的宽度(120px) 比障碍物小
                    person.setX(missiles[i].getX() - Missile.WIDTH);
                } else {
                    // 右碰撞
                    person.setX(missiles[i].getX() + Missile.WIDTH);
                }
            }
        }

        // 人物与鱼叉是否碰撞
        for (int i = 0; i < harpoons.length; i++){
            if (person.getX() + Person.WIDTH >= harpoons[i].getX() &&
                    person.getX() <= harpoons[i].getX() + Harpoon.WIDTH &&
                    person.getY() + Person.HEIGHT >= harpoons[i].getY() &&
                    person.getY() <= harpoons[i].getY() + Harpoon.HEIGHT){
                if (person.getX() + Person.WIDTH <= harpoons[i].getX() + Harpoon.WIDTH){
                    // 左碰撞
                    person.setX(harpoons[i].getX() - Harpoon.WIDTH);
                } else {
                    // 右碰撞
                    person.setX(harpoons[i].getX() + Harpoon.WIDTH);
                }
            }
        }

        // 人物与金币是否碰撞
        for (int i = 0; i < golds.length; i++){
            if (person.getX() + Person.WIDTH >= golds[i].getX() &&
                    person.getX() <= golds[i].getX() + Gold.WIDTH &&
                    person.getY() + Person.HEIGHT >= golds[i].getY() &&
                    person.getY() <= golds[i].getY() + Gold.HEIGHT){
                if (person.getX() + Person.WIDTH <= golds[i].getX() + Gold.WIDTH){
                    // 删除当前金币
                    golds[i] = golds[golds.length -1];
                    golds = Arrays.copyOf(golds, golds.length - 1);
                    // 玩家加分
                    int score = person.getScore();
                    person.setScore(score += 10);
                }
            }
        }
    }

    /**
     * 结束游戏
     */
    public void gameOver(){
        if (person.outOfBounds()){
            // 程序结束
            isGameOver = true;
            // 结束界面 -- 暂未实现

            // 数据清空
            person = new Person();
            crabs = new Crab[] {};
            missiles = new Missile[] {};
        }
    }

    /**
     * 程序启动
     */
    public void start(){
        // 创建线程并启动
        new Thread(){
            public void run(){
                while (!isGameOver){
                    if (flag){
                        // 生成障碍物
                        produceObstacle();
                        // 移动
                        step();
                        // 碰撞
                        collide();
                        // 游戏结束
                        gameOver();
                    }
                    // 重绘方法
                    repaint();
                    try {
                        Thread.sleep(60);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        // 获取玩家当前位置
        int x = person.getX();
        int y = person.getY();
        int x_ = pet.getX();
        int y_ = pet.getY();

        // 上
        if (e.getKeyCode() == KeyEvent.VK_UP && y > 10 && y_ > 10){
            person.setY(y - 25);
            pet.setY(y - 25);
        }

        // 下
        if (e.getKeyCode() == KeyEvent.VK_DOWN && y <= 560 && y_ < 560){
            person.setY(y + 30);
            pet.setY(y - 30);
        }

        // 左
        if (e.getKeyCode() == KeyEvent.VK_LEFT && x >= 0){
            person.setX(x - 30);
            pet.setX(x_ - 30);
        }

        // 右
        if (e.getKeyCode() == KeyEvent.VK_RIGHT){
            person.setX(x + 22);
            pet.setX(x_ + 22);
            // 人物到了右边界
            if (x >= GameFrame.WIDTH - Person.WIDTH){
                person.setX(GameFrame.WIDTH - Person.WIDTH);
            }
            // 宠物到了右边界
            if (x_ >= GameFrame.WIDTH - Pet.WIDTH){
                pet.setX(GameFrame.WIDTH - Pet.WIDTH);
            }
        }

        // 暂停
        if (e.getKeyCode() == KeyEvent.VK_SPACE){
            flag = !flag;
        }

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }
}
